﻿using System.Collections.Generic;
using System.Collections;
using System;
using System.Threading;
using LuaInterface;
using YanhuaMMO;
using System.Collections.Concurrent;
using System.IO;
using System.Net.Sockets;
using System.Net;
using SimpleJSON;
using UnityEngine.Networking;
using System.Reflection;
using System.Linq;
using System.Security.Cryptography;
using UnityEngine.Serialization;
using GLib;
using NPOI.SS.Formula.Functions;
using UnityEngine;
using Random = System.Random;

public class WebMsgManager : Manager
{
    byte[] lenBuffer = new byte[4];
    byte[] sendLenBuffer = new byte[4];
    STDPipe recvPipe = new STDPipe();
    //STDPipe sendPipe = new STDPipe();

    private DateTime beginTime = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
    private long lastTime = 0;

    SharedMem recvMem = new SharedMem();
    SharedMem recvMsgMem = new SharedMem();
    //SharedMem sendMem = new SharedMem();

    // public class MsgInfo
    // {
    //     public LuaFunction onMessage;
    //     public string type;
    //     //public Packet packet;
    // }
    public enum NetState
    {
        ENetStateNone = 0,
        ENetStateWaitConnect,
        ENetStateConnectSuccess,
        ENetStateCannotConnect,
    }

    public int eventFlag = 21586;

    public class ServerInfo
    {
        public string Name;
        public string Addr;
        public string Pwd;
        public int Port;
        public Socket Socket;
        public NetState NetState;
        public LuaFunction Callback;
        public object Args;
        public ByteBuffer Buffer;
        public Random ran = new Random();
    }

    private class ServerBuffer
    {
        public ServerInfo Server;
        public ByteBuffer Buffer;
        public int MsgId;
    }
    // public class 
    // public Queue<>
    [NoToLua] public ServerInfo serverInfo = null;
    [NoToLua] public ServerInfo sceneserverInfo = null; //战场服务器连接
    //public Dictionary<string, ServerInfo> serverList = new Dictionary<string, ServerInfo>();
    // public delegate void MsgHandler(byte type, Packet p);
    // public Queue<MsgInfo> _toDoMessage = new Queue<MsgInfo>();
    // public Queue<Packet> _toDo = new Queue<Packet>();
    // public Dictionary<string, LuaFunction> _onCmds = new Dictionary<string, LuaFunction>();


    //方法待定
    // private LuaFunction _callBack;

    public static int Index = 1;
    public static int MsgOrder = 1;
    public static int SceneMsgOrder = 1;


    //
    // public List<int> hasSendMsgOrders = new List<int>();
    // public Dictionary<int, LuaFunction> protoCallback;
    private const string EncryptKey = "O6QkewhhDQNMs4DraYn5wVHPpqXtoRkj";
    private static WebMsgManager instance;
    private static ServerBuffer cacherButter;

    private void Awake()
    {
        instance = this;

        recvPipe.Init(STDPipe.MIN_PIPE_LENGTH);
        //sendPipe.Init(STDPipe.MIN_PIPE_LENGTH*2);
    }

    private static void DisconnectCallback(IAsyncResult ar)
    {
        // Retrieve the socket from the state object.     
        var socket = (Socket)ar.AsyncState;

        // Complete sending the data to the remote device.     
        socket.EndDisconnect(ar);
        socket.Close();
        socket = null;
    }
    private static void SceneDisconnectCallback(IAsyncResult ar)
    {
        // Retrieve the socket from the state object.     
        var socket = (Socket)ar.AsyncState;

        // Complete sending the data to the remote device.     
        socket.EndDisconnect(ar);
        socket.Close();
        socket = null;
    }
    private static void SendCallback(IAsyncResult ar)
    {
        try
        {
            // Retrieve the socket from the state object.     
            var handler = (ServerBuffer) ar.AsyncState;

            // Complete sending the data to the remote device.     
            handler.Server.Socket.EndSend(ar);
            handler.Buffer.FreeBuffer();

            WebMsgManager.instance.EraseSendBuffer();
        }
        catch (Exception e)
        {
            Util.LogError(e.Message);
            cacherButter = (ServerBuffer) ar.AsyncState;
        }
    }

    private static void SceneSendCallback(IAsyncResult ar)
    {
        try
        {
            // Retrieve the socket from the state object.     
            var handler = (ServerBuffer)ar.AsyncState;

            // Complete sending the data to the remote device.     
            handler.Server.Socket.EndSend(ar);
            //handler.Buffer = null;

            WebMsgManager.instance.EraseSendBuffer();
        }
        catch (Exception e)
        {
            cacherButter = (ServerBuffer)ar.AsyncState;
        }
    }

    // 重连成功后补发消息
    public void ReConnectSuccessCallBack(int msgId, ByteBuffer msg, string serverName = "", int showWaiting = 1,
        LuaFunction callback = null)
    {
        SendByteBuffMsg(msgId, msg);
    }

    public void SendSceneByteBuffMsg(int msgId, ByteBuffer msg, string serverName = "", int showWaiting = 1,
        LuaFunction callback = null)
    {
        if (!AppConst.sceneconnect)
            return;

        if (serverName.Length == 0)
            serverName = "common";

        //if (!serverList.ContainsKey(serverName))
        // {
        //     return;
        // }
        if (sceneserverInfo == null || sceneserverInfo.Name != serverName)
        {
            return;
        }

        var server = sceneserverInfo;
        var indexKey = server.ran.Next(1, int.MaxValue);
        msg.SetInt(8, indexKey);
        msg.SetInt(12, msgId);
        msg.SetInt(16, SceneMsgOrder);
        var data = msg.Buffer;
        //Debug.Log("msgID:"+msgId +" indexKey："+ indexKey+" msgOrder："+ MsgOrder);
        SceneMsgOrder++;
        if (server.Socket != null && server.Socket.Connected)
        {
            var buff = new ServerBuffer()
            {
                Server = server,
                Buffer = msg,
                MsgId = msgId,
            };
            data = Encrypt(indexKey, data, msg.Length);
            /*
            //----------------Write buffer pool-----------------------------

            //write msg length
            int msgLen = msg.Length;
            byte[] msgLenBuffer = intToBytes(msgLen);

            uint length = 4;
            uint leftLen = 4;
            int beginData = sendPipe.PrepareMsg(ref length);
            if (length < 4 && beginData >= 0)
            {
                sendPipe.WriteBuffer(length, msgLenBuffer, 0);
                leftLen = 4 - length;
                sendPipe.ConfirmAddMsg((uint)beginData, length);

                length = leftLen;

                sendPipe.WriteBuffer(leftLen, msgLenBuffer, 4 - leftLen);
                sendPipe.ConfirmAddMsg((uint)beginData, leftLen);
            }
            else if (beginData >= 0)
            {
                sendPipe.WriteBuffer(4, msgLenBuffer, 0);
                sendPipe.ConfirmAddMsg((uint)beginData, 4);
            }
            //end
            //write msg buffer
            uint unLeftSize = (uint)msg.Length;
            uint freeDataLen = unLeftSize;
            beginData = sendPipe.PrepareMsg(ref freeDataLen);

            if (freeDataLen < unLeftSize && beginData >= 0)
            {
                sendPipe.ConfirmAddMsg((uint)beginData, freeDataLen);
                beginData = sendPipe.PrepareMsg(ref freeDataLen);
            }
            sendPipe.WriteBuffer((uint)msg.Length, data, 0);
            sendPipe.ConfirmAddMsg((uint)beginData, (uint)msg.Length);
            //end
            */

            //server.Socket.BeginSend(sendPipe.m_pMemPool, beginData, msg.Length, 0, SceneSendCallback, buff);
            server.Socket.BeginSend(data, 0, msg.Length, 0, SceneSendCallback, buff);
        }
    }
    protected byte[] intToBytes(int value)
    {
        byte[] src = new byte[4];
        src[3] = (byte)((value >> 24) & 0xFF);
        src[2] = (byte)((value >> 16) & 0xFF);
        src[1] = (byte)((value >> 8) & 0xFF);//高8位
        src[0] = (byte)(value & 0xFF);//低位
        return src;
    }

    public void EraseSendBuffer()
    {
        /*
        if (sendPipe.Peek(sendLenBuffer, 4))
        {
            int len = (sendLenBuffer[3] << 24) + (sendLenBuffer[2] << 16) + (sendLenBuffer[1] << 8) + sendLenBuffer[0];

            if (sendPipe.GetDataLen() >= len + 4)
            {
                uint unTempLeftSize = 4;

                while (unTempLeftSize > 0)
                {
                    uint freeDataLen = unTempLeftSize;
                    uint pTempData = sendPipe.GetData(ref freeDataLen);

                    if (freeDataLen > unTempLeftSize)
                    {
                        freeDataLen = unTempLeftSize;
                    }

                    sendPipe.ReturnMsgBuff(pTempData, freeDataLen);
                    unTempLeftSize -= freeDataLen;
                }

                {
                    unTempLeftSize = (uint)len;

                    uint freeDataLen = unTempLeftSize;
                    uint pTempData = sendPipe.GetData(ref freeDataLen);
                    if (freeDataLen < unTempLeftSize)
                    {
                        sendPipe.ReturnMsgBuff(pTempData, freeDataLen);
                        freeDataLen = unTempLeftSize;
                        pTempData = sendPipe.GetData(ref freeDataLen);
                    }
                    sendPipe.ReturnMsgBuff(pTempData, unTempLeftSize);
                }
            }
        }
        */
    }

    public void SendByteBuffMsg(int msgId, ByteBuffer msg, string serverName = "", int showWaiting = 1,
        LuaFunction callback = null)
    {
        if (!AppConst.connect)
            return;

        if (serverName.Length == 0)
            serverName = "common";

        //if (!serverList.ContainsKey(serverName))
        // {
        //     return;
        // }
        if (serverInfo == null || serverInfo.Name != serverName)
        {
            return;
        }

        var server = serverInfo;
        var indexKey = server.ran.Next(1, int.MaxValue);
        msg.SetInt(8, indexKey);
        msg.SetInt(12, msgId);
        msg.SetInt(16, MsgOrder);
        var data = msg.Buffer;
        //Debug.Log("msgID:"+msgId +" indexKey："+ indexKey+" msgOrder："+ MsgOrder);
        MsgOrder++;
        if (server.Socket != null && server.Socket.Connected)
        {
            var buff = new ServerBuffer()
            {
                Server = server,
                Buffer = msg,
                MsgId = msgId,
            };
            data = Encrypt(indexKey, data,msg.Length);

            /*
            //----------------Write buffer pool-----------------------------

            //write msg length
            int msgLen = msg.Length;
            byte[] msgLenBuffer = intToBytes(msgLen);

            uint length = 4;
            uint leftLen = 4;
            int beginData = sendPipe.PrepareMsg(ref length);
            if (length < 4 && beginData >= 0)
            {
                sendPipe.WriteBuffer(length, msgLenBuffer, 0);
                leftLen = 4 - length;
                sendPipe.ConfirmAddMsg((uint)beginData, length);

                length = leftLen;

                sendPipe.WriteBuffer(leftLen, msgLenBuffer, 4- leftLen);
                sendPipe.ConfirmAddMsg((uint)beginData, leftLen);
            }
            else if (beginData >= 0)
            {
                sendPipe.WriteBuffer(4, msgLenBuffer, 0);
                sendPipe.ConfirmAddMsg((uint)beginData, 4);
            }
            //end
            //write msg buffer
            uint unLeftSize = (uint)msg.Length;
            uint freeDataLen = unLeftSize;
            beginData = sendPipe.PrepareMsg(ref freeDataLen);

            if( freeDataLen < unLeftSize && beginData >= 0 )
            {
                sendPipe.ConfirmAddMsg((uint)beginData, freeDataLen);
                beginData = sendPipe.PrepareMsg(ref freeDataLen);
            }
            sendPipe.WriteBuffer((uint)msg.Length, data,0);
            sendPipe.ConfirmAddMsg((uint)beginData, (uint)msg.Length);
            //end
            */

            //server.Socket.BeginSend(sendPipe.m_pMemPool, beginData, msg.Length, 0, SendCallback, buff);
            server.Socket.BeginSend(data, 0, msg.Length, 0, SendCallback, buff);
        }
        else
        {
            cacherButter = new ServerBuffer()
            {
                Server = server,
                Buffer = msg,
                MsgId = msgId,
            };
        }
    }


    public void SendHttpRequest(string httpUrl, string paramData, LuaFunction httpBackCall)
    {
        StartCoroutine(SendHttp(httpUrl, paramData, httpBackCall));
    }

    public bool IsConnected()
    {
        if( serverInfo != null && serverInfo.NetState == NetState.ENetStateConnectSuccess )
        {
            return true;
        }
        return false;
    }

    public void Update()
    {
        if (serverInfo != null )

        {
            switch (serverInfo.NetState)
            {
                case NetState.ENetStateNone:
                case NetState.ENetStateCannotConnect:
                    if (serverInfo.Callback != null)
                    {
                        serverInfo.Callback.Call(false);
                        serverInfo.Callback = null;
                        serverInfo.Args = null;
                    }
                    break;
                case NetState.ENetStateWaitConnect:
                    WaitConnect();
                    break;
                case NetState.ENetStateConnectSuccess:
                    RecvData(serverInfo);
                    if (serverInfo.Callback != null)
                    {
                        serverInfo.Callback.Call(serverInfo.Args);

                        serverInfo.Callback = null;
                        serverInfo.Args = null;
                    }

                    WaitPacket(serverInfo.Name, serverInfo);
                    break;
                default:
                    WaitPacket(serverInfo.Name, serverInfo);
                    break;
            }
        }

        if (sceneserverInfo != null )
        {
            switch (sceneserverInfo.NetState)
            {
                case NetState.ENetStateNone:
                case NetState.ENetStateCannotConnect:
                    if (sceneserverInfo.Callback != null)
                    {
                        sceneserverInfo.Callback.Call(false);
                        sceneserverInfo.Callback = null;
                        sceneserverInfo.Args = null;
                    }
                    break;
                case NetState.ENetStateWaitConnect:
                    WaitConnect();
                    break;
                case NetState.ENetStateConnectSuccess:
                    RecvData(sceneserverInfo);
                    if (sceneserverInfo.Callback != null)
                    {
                        sceneserverInfo.Callback.Call(sceneserverInfo.Args);

                        sceneserverInfo.Callback = null;
                        sceneserverInfo.Args = null;
                    }

                    WaitPacket(sceneserverInfo.Name, sceneserverInfo);
                    break;
                default:
                    WaitPacket(sceneserverInfo.Name, sceneserverInfo);
                    break;
            }
        }

        if (cacherButter != null)
        {
            Util.Log("链接断开:" + cacherButter.MsgId);
            WebMsgManager.instance.DisConnect();
            Util.CallMethod("ConnectManager", "TryConnect", cacherButter.MsgId, cacherButter.Buffer);

            cacherButter = null;
        }
    }

    private void WaitPacket(string serverName, ServerInfo server)
    {
        if (!server.Socket.Connected)
        {
            return;
        }

        if (!ProcessInput(serverName, server))
        {
            //告诉系统说网络关闭
            //
        }
    }

    public static byte[] Encrypt(int keyIndex, byte[] data,int length)
    {
        for (int i = 12; i < length; ++i)
        {
            data[i] ^= (byte)(keyIndex >> 2);
        }

        return data;
    }

    public bool RecvData(ServerInfo server)
    {
        if (!server.Socket.Connected || server.Socket.Available <= 0) return true;
        int bufferSize = server.Socket.Available;
        if (bufferSize > 0)
        {
            //byte[] buffer = new byte[bufferSize];
            byte[] buffer = recvMem.CreateBuffer(bufferSize);
            var nReceived = server.Socket.Receive(buffer, bufferSize, SocketFlags.None);
            if (nReceived <= 0)
            {
                return false;
            }

            uint unLeftSize = (uint) nReceived;
            uint freeDataLen = unLeftSize;
            int beginData = recvPipe.PrepareMsg(ref freeDataLen);

            while (freeDataLen < unLeftSize && beginData >= 0)
            {
                recvPipe.WriteBuffer(freeDataLen, buffer, (uint) nReceived - unLeftSize);
                unLeftSize = unLeftSize - freeDataLen;
                recvPipe.ConfirmAddMsg((uint) beginData, freeDataLen);
            }

            if (beginData >= 0 && unLeftSize > 0)
            {
                recvPipe.WriteBuffer(unLeftSize, buffer, (uint) nReceived - unLeftSize);
                recvPipe.ConfirmAddMsg((uint) beginData, unLeftSize);
            }

            //buffer = null;
            return true;
        }

        return false;
    }

    public int GetMsg(ref byte[] buffer)
    {
        if (recvPipe.Peek(lenBuffer, 4))
        {
            int len = (lenBuffer[0] << 24) + (lenBuffer[1] << 16) + (lenBuffer[2] << 8) + lenBuffer[3];

            if (recvPipe.GetDataLen() >= len+4)
            {
                uint unTempLeftSize = 4;

                while (unTempLeftSize > 0)
                {
                    uint freeDataLen = unTempLeftSize;
                    uint pTempData = recvPipe.GetData(ref freeDataLen);

                    if (freeDataLen > unTempLeftSize)
                    {
                        freeDataLen = unTempLeftSize;
                    }

                    recvPipe.ReturnMsgBuff(pTempData, freeDataLen);
                    unTempLeftSize -= freeDataLen;
                }

                //buffer = new byte[len];
                buffer = recvMsgMem.CreateBuffer(len);

                unTempLeftSize = (uint) len;

                while (unTempLeftSize > 0)
                {
                    uint freeDataLen = unTempLeftSize;
                    uint pTempData = recvPipe.GetData(ref freeDataLen);

                    if (freeDataLen > unTempLeftSize)
                    {
                        freeDataLen = unTempLeftSize;
                    }

                    recvPipe.ReadBuffer(freeDataLen, buffer, (uint) len - unTempLeftSize);
                    recvPipe.ReturnMsgBuff(pTempData, freeDataLen);
                    unTempLeftSize -= freeDataLen;
                }

                return len;
            }
        }

        return 0;
    }

    //TODO 这块逻辑整体不是很好，需要修改。解包要有整体缓冲区控制，buff缓冲有整包拿取 shazhifeng 2021-1-8 后期客户端自行修改吧
    private bool ProcessInput(string serverName, ServerInfo server)
    {
        //Debug.Log("ProcessInput Start");
        byte[] buffer = null;

        while (GetMsg(ref buffer) > 0 && buffer != null)
        {
            server.Buffer = new ByteBuffer(buffer);
            handlerMsg(server.Buffer);

            //buffer = null;
        }

        /*
        if (!server.Socket.Connected || server.Socket.Available <= 0) return true;
        while (server.Socket.Available > 0)
        {
            if (server.Buffer == null)
            {
                //不满足4个字节长度都没有，等下一帧在解析
                if (server.Socket.Available < 4)
                {
                    return true;
                }

                byte[] sLength = new byte[4];
                var nReceived = server.Socket.Receive(sLength, 4, SocketFlags.None);
                //没有数据,断线了
                if (nReceived <= 0)
                {
                    return false;
                }

                Array.Reverse(sLength);
                var nLength = BitConverter.ToUInt32(sLength, 0);
                server.Buffer = new ByteBuffer((int) nLength) {Length = (int) nLength};
            }

            //字节不够，等下一帧
            if (server.Socket.Available < server.Buffer.Length)
            {
                return true;
            }

            var receive = server.Socket.Receive(server.Buffer.Buffer, server.Buffer.Length, SocketFlags.None);
            //没有数据,断线了
            if (receive <= 0)
            {
                return false;
            }

            try
            {
                handlerMsg(server.Buffer);
            }
            catch (Exception e)
            {
                //Debug.LogError("协议处理错误"+e.Message);
            }
            finally
            {
                server.Buffer = null;
            }
        }
        */
        return true;
    }

    /**
     * 得到完整包，处理消息
     */
    public void handlerMsg(ByteBuffer buff)
    {
        buff.ReadByte();
        var msgId = buff.ReadInt32();
        //Debug.Log("receive msgID:"+msgId );
        //Util.CallMethod("NetMsgDecoder", "msgHandler", msgId, buff);
        lastTime = (DateTime.Now - beginTime).Milliseconds;
        LuaManager.RecvNetMessage(msgId, buff);
        long delta = (DateTime.Now - beginTime).Milliseconds - lastTime;
        //if(delta > 50)
        //    Util.LogError("Receive Msg:" + msgId + "With Time:"+ delta);
    }

    public void WaitConnect()
    {
    }

    private static IEnumerator SendHttp(string url, string paramData, LuaFunction callback)
    {
        byte[] bodyRaw = System.Text.Encoding.UTF8.GetBytes(paramData);

        var request = new UnityWebRequest(url, "POST") {uploadHandler = new UploadHandlerRaw(bodyRaw)};


        request.SetRequestHeader("Content-Type", "application/json;charset=utf-8");
        request.SetRequestHeader("Authorization", AppConst.UserToken);


        request.downloadHandler = new DownloadHandlerBuffer();

        yield return request.SendWebRequest();

        if (request.isNetworkError)
        {
            //Debug.Log("http 请求错误:" + request.error);
        }
        else
        {
            var result = request.downloadHandler.text;

            if (callback != null)
                callback.Call(result);
        }
    }
    private void SceneConnect(IAsyncResult iar)
    {
        var client = (Socket)iar.AsyncState;
        if (sceneserverInfo != null && sceneserverInfo.Socket == client)
        //foreach (var server in serverList.Where(server => server.Value.Socket == client))
        {
            try
            {
                if (client.Connected)
                {
                    //先发加密密钥
                    // List<byte> byteArray = System.Text.Encoding.ASCII.GetBytes (server.Value.pwd).ToList();
                    // server.Value.socket.BeginSend(byteArray.ToArray(), 0, byteArray.Count,0, new AsyncCallback(SendCallback), server.Value.socket);
                    AppConst.sceneconnect = true;

                    client.EndConnect(iar);
                    sceneserverInfo.NetState = NetState.ENetStateConnectSuccess;
                }
                else
                {
                    sceneserverInfo.NetState = NetState.ENetStateCannotConnect;
                    client.EndConnect(iar);
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e.ToString());
            }
        }
    }

    //手动释放内存
    private void Connect(IAsyncResult iar)
    {
        var client = (Socket) iar.AsyncState;
        if (serverInfo != null && serverInfo.Socket == client)
            //foreach (var server in serverList.Where(server => server.Value.Socket == client))
        {
            try
            {
                if (client.Connected)
                {
                    //先发加密密钥
                    // List<byte> byteArray = System.Text.Encoding.ASCII.GetBytes (server.Value.pwd).ToList();
                    // server.Value.socket.BeginSend(byteArray.ToArray(), 0, byteArray.Count,0, new AsyncCallback(SendCallback), server.Value.socket);
                    AppConst.connect = true;

                    client.EndConnect(iar);
                    serverInfo.NetState = NetState.ENetStateConnectSuccess;
                }
                else
                {
                    serverInfo.NetState = NetState.ENetStateCannotConnect;
                    client.EndConnect(iar);
                }
            }
            catch (Exception e)
            {
                serverInfo.NetState = NetState.ENetStateCannotConnect;
                Console.WriteLine(e.ToString());
            }
        }
    }

    public void DisConnectServer(string serverName = "")
    {
        if (serverName.Length == 0)
        {
            serverName = "common";
        }

        //if (!serverList.ContainsKey(serverName))
        // {
        //     return;
        // }
        if (serverInfo == null || serverInfo.Name != serverName) return;
        //var server = serverList[serverName];
        if (serverInfo.Socket != null && serverInfo.Socket.Connected)
        {
            //serverInfo.Socket.Shutdown(SocketShutdown.Both);
            serverInfo.Socket.BeginDisconnect(false, new AsyncCallback(DisconnectCallback), serverInfo.Socket);
        }

        serverInfo.Buffer = null;
        serverInfo.NetState = NetState.ENetStateNone;
        //serverList.Remove(serverName);
    }

    public void DisConnectSceneServer(string serverName = "")
    {
        if (serverName.Length == 0)
        {
            serverName = "common";
        }

        //if (!serverList.ContainsKey(serverName))
        // {
        //     return;
        // }
        if (sceneserverInfo == null || sceneserverInfo.Name != serverName) return;
        //var server = serverList[serverName];
        if (sceneserverInfo.Socket != null && sceneserverInfo.Socket.Connected)
        {
            //sceneserverInfo.Socket.Shutdown(SocketShutdown.Both);
            sceneserverInfo.Socket.BeginDisconnect(false, new AsyncCallback(SceneDisconnectCallback), sceneserverInfo.Socket);
        }

        sceneserverInfo.Buffer = null;
        sceneserverInfo.NetState = NetState.ENetStateNone;
        //serverList.Remove(serverName);
    }

    public void ConnectSceneServer(string addr, int port, string pwd = "", string serverName = "",
        LuaFunction callback = null, object objs = null)
    {
        if (AppConst.sceneconnect)
            return;
        if (serverName.Length == 0)
        {
            serverName = "common";
        }

        ServerInfo server = sceneserverInfo;
        if (sceneserverInfo != null && sceneserverInfo.Name == serverName)
        // if (serverList.ContainsKey(serverName))
        {
            // server = serverList[serverName];
            DisConnectSceneServer(serverName);
        }
        else
        {
            server = new ServerInfo();
            sceneserverInfo = server;
        }

        server.Name = serverName;
        server.Addr = addr;
        server.Port = port;
        server.Pwd = pwd;
        server.Socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        server.Callback = callback;
        server.Args = objs;
        IPAddress ip = IPAddress.Parse(addr);
        IPEndPoint iep = new IPEndPoint(ip, port);
        server.Socket.Blocking = false;
        server.Socket.BeginConnect(iep, SceneConnect, server.Socket);
        server.NetState = NetState.ENetStateWaitConnect;
        //serverList[serverName] = server;
    }

    public void ConnectServer(string addr, int port, string pwd = "", string serverName = "",
        LuaFunction callback = null, object objs = null)
    {
        if (AppConst.connect)
            return;
        if (serverName.Length == 0)
        {
            serverName = "common";
        }

        ServerInfo server = serverInfo;
        if (serverInfo != null && serverInfo.Name == serverName)
            // if (serverList.ContainsKey(serverName))
        {
            // server = serverList[serverName];
            DisConnectServer(serverName);
        }
        else
        {
            server = new ServerInfo();
            serverInfo = server;
        }

        server.Name = serverName;
        server.Addr = addr;
        server.Port = port;
        server.Pwd = pwd;
        server.Socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        server.Callback = callback;
        server.Args = objs;
        IPAddress ip = IPAddress.Parse(addr);
        IPEndPoint iep = new IPEndPoint(ip, port);
        server.Socket.Blocking = false;
        server.Socket.BeginConnect(iep, Connect, server.Socket);
        server.NetState = NetState.ENetStateWaitConnect;
        //serverList[serverName] = server;
    }
    //connect server
    // public void ConnectServer(string ip,int port ,int oneOrTwo)
    // {
    //     if (AppConst.connect)
    //         return;
    //     Program.ip = ip;
    //     Program.port = port;
    //
    //     ParameterizedThreadStart ParStart = new ParameterizedThreadStart(MyMethod);
    //
    //     Thread tempThread = new Thread(ParStart);
    //     tempThread.Start(oneOrTwo);
    // }

    //disconnect server
    public void DisConnect()
    {
        AppConst.connect = false;
        DisConnectServer();
    }

    public void SceneDisConnect()
    {
        AppConst.sceneconnect = false;
        DisConnectSceneServer();
    }


    #region read server data

    public void WriteInt(ByteBuffer buf, int value)
    {
        ProtobufUtil.WriteRawVarInt32(buf, value);
    }

    public void WriteInt(ByteBuffer buf, uint value)
    {
        ProtobufUtil.WriteRawVarUint32(buf, value);
    }

    public void WriteString(ByteBuffer buf, string value)
    {
        //为空处理
        if (value == null)
        {
            ProtobufUtil.WriteRawVarInt32(buf, 0);
            return;
        }

        byte[] bytes = System.Text.Encoding.UTF8.GetBytes(value);
        ProtobufUtil.WriteRawVarInt32(buf, bytes.Length);
        buf.WriteBytes(bytes);
    }

    public void WriteLong(ByteBuffer buf, long value)
    {
        ProtobufUtil.WriteRawVarUint64(buf, value);
    }

    public void WriteShort(ByteBuffer buf, short value)
    {
        ProtobufUtil.WriteRawVarInt32(buf, value);
    }

    public void WriteSbyte(ByteBuffer buf, sbyte value)
    {
        ProtobufUtil.WriteRawVarInt32(buf, value);
    }

    public void WriteByte(ByteBuffer buf, byte value)
    {
        buf.WriteByte(value);
    }

    public void WriteBytes(ByteBuffer buf, byte[] value)
    {
        //为空处理
        if (value == null)
        {
            ProtobufUtil.WriteRawVarInt32(buf, 0);
            return;
        }

        ProtobufUtil.WriteRawVarInt32(buf, value.Length);
        buf.WriteBytes(value);
    }
	public void WriteFloat(ByteBuffer buf,float value)
	{
		buf.WriteFloat(value);
	}

	public void WriteId(ByteBuffer buf, long value)
    {
        buf.WriteLong(value);
    }

    public int ReadInt(ByteBuffer buf)
    {
        return ProtobufUtil.ReadRawVarInt32(buf);
    }

    public uint ReadUint(ByteBuffer buf)
    {
        return ProtobufUtil.ReadRawVarUint32(buf);
    }

    public string ReadString(ByteBuffer buf)
    {
        int length = ProtobufUtil.ReadRawVarInt32(buf);
        if (length <= 0)
            return null;
        if (buf.ReadableBytes < length)
            return null;
        var bytes = buf.ReadBytes(length);
        return System.Text.Encoding.UTF8.GetString(bytes);
    }

    public long ReadLong(ByteBuffer buf)
    {
        return ProtobufUtil.ReadRawVarUint64(buf);
    }

    public long ReadId(ByteBuffer buf)
    {
        return buf.ReadLong();
    }
	public float ReadFloat(ByteBuffer buf)
	{
		return buf.ReadFloat();
	}


	public short ReadShort(ByteBuffer buf)
    {
        return (short) ProtobufUtil.ReadRawVarInt32(buf);
    }

    public byte ReadByte(ByteBuffer buf)
    {
        return buf.ReadByte();
    }

    public sbyte ReadSbyte(ByteBuffer buf)
    {
        return (sbyte) buf.ReadByte();
    }

    public byte[] ReadBytes(ByteBuffer buf)
    {
        int length = ProtobufUtil.ReadRawVarInt32(buf);
        if (length == 0)
            return new byte[0];
        var bytes = buf.ReadBytes(length);
        return bytes;
    }

    public ByteBuffer createByteBuff()
    {
        //byte[] buffer = sendMem.CreateBuffer(1024);
        //return new ByteBuffer(buffer,0);   
        return new SendByteBuffer();
    }

    public ByteBuffer createByteBuffSize(int size)
    {
        /*
        uint unLeftSize = (uint)size;
        uint freeDataLen = unLeftSize;

        int beginData = sendPipe.PrepareMsg(ref freeDataLen);

        while (freeDataLen < unLeftSize && beginData >= 0)
        {
            recvPipe.WriteBuffer(freeDataLen, buffer, (uint)nReceived - unLeftSize);
            unLeftSize = unLeftSize - freeDataLen;
            recvPipe.ConfirmAddMsg((uint)beginData, freeDataLen);
        }

        if (beginData >= 0 && unLeftSize > 0)
        {
            recvPipe.WriteBuffer(unLeftSize, buffer, (uint)nReceived - unLeftSize);
            recvPipe.ConfirmAddMsg((uint)beginData, unLeftSize);
        }
        */
        //byte[] buffer = sendMem.CreateBuffer(size);
        //return new ByteBuffer(buffer,0);
        return new ByteBuffer(size);
    }

    #endregion
}